package jwt0

import (
	"gitee.com/sdynasty/clever/errors"
	"github.com/dgrijalva/jwt-go"
	"time"
)

const (
	_secret = "clever-secret"

	// bearerWord the bearer key word for authorization
	bearerWord string = "Bearer"

	// bearerFormat authorization token format
	bearerFormat string = "Bearer %s"

	// authorizationKey holds the key used to store the JWT Token in the request tokenHeader.
	authorizationKey string = "Authorization"

	// reason holds the error reason.
	reason string = "UNAUTHORIZED"
)

var (
	ErrMissingJwtToken        = errors.Unauthorized(reason, "JWT token is missing")
	ErrMissingKeyFunc         = errors.Unauthorized(reason, "keyFunc is missing")
	ErrTokenInvalid           = errors.Unauthorized(reason, "Token is invalid")
	ErrTokenExpired           = errors.Unauthorized(reason, "JWT token has expired")
	ErrTokenParseFail         = errors.Unauthorized(reason, "Fail to parse JWT token ")
	ErrUnSupportSigningMethod = errors.Unauthorized(reason, "Wrong signing method")
	ErrWrongContext           = errors.Unauthorized(reason, "Wrong context for middleware")
	ErrNeedTokenProvider      = errors.Unauthorized(reason, "Token provider is missing")
	ErrSignToken              = errors.Unauthorized(reason, "Can not sign token.Is the key correct?")
	ErrGetKey                 = errors.Unauthorized(reason, "Can not get key while signing token")
)

type Claims struct {
	UserId   string
	ServerNo string
	jwt.StandardClaims
}

// CreateJwtSignedString 创建签名串
func CreateJwtSignedString(serverNo, userId string) (signedString string, err error) {
	claims := &Claims{
		UserId:         userId,
		ServerNo:       serverNo,
		StandardClaims: jwt.StandardClaims{
			ExpiresAt: time.Now().Add(30 * time.Minute).Unix(),
		},
	}

	token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
	//创建jwt 签名串
	return token.SignedString([]byte(_secret))
}

func ParseJwtSignedString(tokenStr string) (*Claims, error) {
	claims := &Claims{}
	//解析JWT string
	tkn, err := jwt.ParseWithClaims(tokenStr, claims, func(token *jwt.Token) (i interface{}, err error) {
		return []byte(_secret), err
	})

	if err != nil {
		if err == jwt.ErrSignatureInvalid {
			return nil, errors.New("signature invalid")
		}
		return nil, err
	}

	if !tkn.Valid {
		return nil, errors.New("token invalid")
	}
	return claims, nil
}

